Au niveau des agents de la voirie de Bondy, un besoin est exprimé. Il faut distinguer, du premier coup d’oeil, le domaine public et privé. La précédente application cadastrale leur apportait cet élément.
Dans une la réunion des géomaticiens du 14/04/2022, Laurent Soulié (Bobigny) a proposé une thématique intéressante sur la notion public / privé autour du cadastre.
Par ailleurs, dans le cadastre, il y a le champs classant la personne morale.
https://www.collectivites-locales.gouv.fr/sites/default/files/migration/ffs_2020_proprietaires.pdf
cat <- c("p. morales non remarquables",
"Etat", "région", "département", "commune"
, "office HLM", "p. morales SEM",
"copro", "associés", "Etablissements publics ou organismes associés")
J’ai donc essayé de répondre au besoin exprimé en voirie à partir de ces 2 éléments.
Ce support est une présentation de la méthode et des outils que j’ai utilisés pour la réunion des géomaticiens du 22 septembre.
library(sf) # géométrie spatiale
## Linking to GEOS 3.9.1, GDAL 3.3.2, PROJ 7.2.1; sf_use_s2() is TRUE
library(mapsf) # cartographie
… Utilisation d’un google drive…
chemin <- "G:/Mon Drive/05_DATA"
Le cadastre millesime 2022, repris sous le plugin Qgis et enregistré en base sqlite.
Il s’agit de récupérer la notion de personne morale (proprietaire) et le dessin des parcelles (parcelle_info).
Un travail est d’abord effectué sur la variable propriété de parcelle_info
# lecture du fichier
cadastre <- st_read(paste0(chemin,"/01_SOCLE/cadastre/cadastre2022.sqlite"), "parcelle_info")
# enregistrement pour présentation
st_write(cadastre, "../data/cadastre.gpkg", "parcelle_info", delete_layer = T)
# lecture
cadastre <- st_read("../data/cadastre.gpkg", "parcelle_info", quiet = T)
# première ligne
cadastre$proprietaire [1]
## [1] "MB7PNW - M AZDAD/TAHAR - Propriétaire|MB7PNX - MME BOUDASDASS/FATIMA - Propriétaire"
La variable propriétaire contient des informations intéressantes, on essaie d’abord d’exploiter le type de propriété, mais c’est surtout le nom qui nous intéresse.
# éclatement chaine proprio
chaine <- strsplit(cadastre$proprietaire, " - ")
# exemple
chaine [[3]]
## [1] "MB8HKP" "M BETARI/NAJAM" "Propriétaire|MB8HKQ"
## [4] "MME BOUDABOUZA/HAYET" "Propriétaire"
# Seul le 1er terme du 2e élément nous intéresse
chaine2 <- sapply(chaine, "[",3)
chaine3 <- strsplit(chaine2, "\\|")
cadastre$type <- sapply (chaine3, "[",1)
table(cadastre$type)
##
## COPROS 27 AVE HENRI BARBUSSE Emphytéote (associé avec P)
## 1 4
## PODOLOGIE Preneur à construction (associé avec B)
## 1 2
## Propriétaire SCI
## 6736 1
## Usufruitier (associé avec N)
## 331
Nous verrons par la suite s’il faut retenir ces modalités.
On isole le nom du propriétaire dans la variable nom.
cadastre <- st_read("../data/cadastre.gpkg", "parcelle_info")
## Reading layer `parcelle_info' from data source
## `C:\Users\tachasa\02_cartos\data\cadastre.gpkg' using driver `GPKG'
## Simple feature collection with 7080 features and 16 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 661077.2 ymin: 6865338 xmax: 663343.6 ymax: 6869045
## Projected CRS: RGF93 / Lambert-93
# on éclate la chaîne
chaine <- strsplit(cadastre$proprietaire, " - ")
# récupération du 2e terme
cadastre$nom <- sapply(chaine, "[",2)
cadastre [is.na(cadastre$proprietaire),]
## Simple feature collection with 4 features and 17 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 661359.2 ymin: 6865597 xmax: 663108.5 ymax: 6867559
## Projected CRS: RGF93 / Lambert-93
## geo_parcelle idu tex geo_section nomcommune codecommune
## 1187 9300100000H0382 0100000H0382 382 9300100000H <NA> <NA>
## 4827 930010000AO0271 010000AO0271 271 930010000AO <NA> <NA>
## 4828 930010000AO0272 010000AO0272 272 930010000AO <NA> <NA>
## 6995 930010000BF0261 010000BF0261 261 930010000BF <NA> <NA>
## surface_geo contenance adresse urbain code comptecommunal voie
## 1187 2028 NA <NA> Non <NA> <NA> <NA>
## 4827 108 NA <NA> Non <NA> <NA> <NA>
## 4828 99 NA <NA> Non <NA> <NA> <NA>
## 6995 47 NA <NA> Non <NA> <NA> <NA>
## proprietaire proprietaire_info lot geom nom
## 1187 <NA> <NA> 93010 MULTIPOLYGON (((661359.2 68... <NA>
## 4827 <NA> <NA> 93010 MULTIPOLYGON (((663095.9 68... <NA>
## 4828 <NA> <NA> 93010 MULTIPOLYGON (((663092.2 68... <NA>
## 6995 <NA> <NA> 93010 MULTIPOLYGON (((661740 6865... <NA>
# Il y a 4 parcelles sans proprio
cadastre$nom [is.na(cadastre$proprietaire)] <- "inconnu"
# suppression des espaces avant et après les noms
cadastre$nom <- gsub("^\\s+|\\s+$", "", cadastre$nom)
# aggregation des parcelles (permet de gérer le pb des parcelles mitoyennes)
agg <- aggregate(cadastre [, ("nom")], by = list(cadastre$nom), length)
# on passe de 7028 à 5476
names(agg)[1:2] <- c("nom", "nb_parcelles")
# sauvegarde du fichier agrégé
st_write(agg, "../data/cadastre.gpkg", "agg", delete_layer = T)
## Deleting layer `agg' using driver `GPKG'
## Writing layer `agg' to data source `../data/cadastre.gpkg' using driver `GPKG'
## Writing 5469 features with 2 fields and geometry type Unknown (any).
Il existe un fichier proprietaire dans la base sqlite, elle contient la personne morale.
proprio <- st_read(paste0(chemin,"/01_SOCLE/cadastre/cadastre2022.sqlite"), "proprietaire")
st_write(proprio, "../data/cadastre.gpkg", "proprio", delete_layer = T)
proprio <- st_read("../data/cadastre.gpkg", "proprio")
## Reading layer `proprio' from data source
## `C:\Users\tachasa\02_cartos\data\cadastre.gpkg' using driver `GPKG'
# on observe le fichier
str(proprio)
## 'data.frame': 20333 obs. of 71 variables:
## $ proprietaire : chr "93*0000101PBCGM5" "93*0000201PBCF6W" "93*0000401PBCNTR" "93*0000501PBCFV2" ...
## $ annee : chr "2021" "2021" "2021" "2021" ...
## $ ccodep : chr "93" "93" "93" "93" ...
## $ ccodir : chr "0" "0" "0" "0" ...
## $ ccocom : chr "010" "010" "010" "010" ...
## $ dnupro : chr "*00001" "*00002" "*00004" "*00005" ...
## $ comptecommunal: chr "930010*00001" "930010*00002" "930010*00004" "930010*00005" ...
## $ dnulp : chr "01" "01" "01" "01" ...
## $ ccocif : chr "4101" "4101" "4101" "4101" ...
## $ dnuper : chr "PBCGM5" "PBCF6W" "PBCNTR" "PBCFV2" ...
## $ ccodro : chr "P" "P" "P" "P" ...
## $ ccodem : chr NA NA NA NA ...
## $ gdesip : chr "1" "1" "1" "1" ...
## $ gtoper : chr "2" "2" "2" "2" ...
## $ ccoqua : chr NA NA NA NA ...
## $ gnexcf : chr NA NA NA NA ...
## $ dtaucf : chr NA NA NA NA ...
## $ dnatpr : chr NA NA NA NA ...
## $ ccogrm : chr "7" "7" "7" "7" ...
## $ dsglpm : chr " " " " " " " " ...
## $ dforme : chr "F001" "F001" "F001" "F001" ...
## $ ddenom : chr "COPROPRIETAIRES DE L'IMMEUBLE DU 25 ALL ANDREA " "COPROPRIETAIRES DE L'IMMEUBLE ALL BOILEAU " "LES COPROPRIETAIRES DE L'IMMEUBLE 20 ALL DES HETRES " "COPROPRIETAIRE DE L'IMMEUBLE 3-3BIS ALL DE LA JARDINIERE ET " ...
## $ gtyp3 : chr "9" "9" "9" "9" ...
## $ dlign3 : chr " " " " " " " " ...
## $ gtyp4 : chr "2" "2" "2" "2" ...
## $ dlign4 : chr "0025 ALL ANDREA " "0005 ALL BOILEAU " "0020 ALL DES HETRES " "0003 ALL DE LA JARDINIERE " ...
## $ gtyp5 : chr "9" "9" "9" "9" ...
## $ dlign5 : chr " " " " " " " " ...
## $ gtyp6 : chr "2" "2" "2" "2" ...
## $ dlign6 : chr "93140 BONDY " "93140 BONDY " "93140 BONDY " "93140 BONDY " ...
## $ ccopay : chr " " " " " " " " ...
## $ ccodep1a2 : chr "93" "93" "93" "93" ...
## $ ccodira : chr "0" "0" "0" "0" ...
## $ ccocom_adr : chr "010" "010" "010" "010" ...
## $ ccovoi : chr "00038" "00059" "00169" "00176" ...
## $ ccoriv : chr "0055" "0710" "4450" "4710" ...
## $ dnvoiri : chr "0025" "0005" "0020" "0003" ...
## $ dindic : chr " " " " " " " " ...
## $ ccopos : chr "93140" "93140" "93140" "93140" ...
## $ dnirpp : chr NA NA NA NA ...
## $ dqualp : chr " " " " " " " " ...
## $ dnomlp : chr " " " " " " " " ...
## $ dprnlp : chr " " " " " " " " ...
## $ jdatnss : chr NA NA NA NA ...
## $ dldnss : chr " " " " " " " " ...
## $ epxnee : chr NA NA NA NA ...
## $ dnomcp : chr NA NA NA NA ...
## $ dprncp : chr NA NA NA NA ...
## $ topcdi : chr NA NA NA NA ...
## $ oriard : chr NA NA NA NA ...
## $ fixard : chr NA NA NA NA ...
## $ datadr : chr NA NA NA NA ...
## $ topdec : chr NA NA NA NA ...
## $ datdec : chr NA NA NA NA ...
## $ dsiren : chr "U08632184" "U08636128" "U08522906" "U08633968" ...
## $ ccmm : chr NA NA NA NA ...
## $ topja : chr " " " " " " " " ...
## $ datja : chr NA NA NA NA ...
## $ anospi : chr NA NA NA NA ...
## $ cblpmo : chr NA NA NA NA ...
## $ gtodge : chr NA NA NA NA ...
## $ gpctf : chr NA NA NA NA ...
## $ gpctsb : chr NA NA NA NA ...
## $ jmodge : chr NA NA NA NA ...
## $ jandge : chr NA NA NA NA ...
## $ jantfc : chr NA NA NA NA ...
## $ jantbc : chr NA NA NA NA ...
## $ dformjur : chr "COP " "COP " "COP " "COP " ...
## $ dnomus : chr " " " " " " " " ...
## $ dprnus : chr " " " " " " " " ...
## $ lot : chr "93010" "93010" "93010" "93010" ...
# Le champs personne morale est ccogrm
table(proprio$ccogrm, useNA = "always")
##
## 0 1 2 3 4 5 6 7 9 <NA>
## 897 15 2 3 16 22 3 582 15 18778
# Beaucoup de propriétaires non catégorisés.
# Le nom du proprio est ddenom, on garde également le siren pour correspondance autre (le siret aurait été mieux ?)
proprio <- proprio [, c("ddenom", "ccogrm", "dsiren")]
names(proprio) <-c("nom", "categorie", "dsiren")
length(proprio$categorie[is.na(proprio$nom)])
## [1] 0
# les propriétaires sans nom ne sont pas catégorisés : il y en 18 653 / 20 333 en 2022
proprio <- proprio [!is.na(proprio$nom),]
table(is.na(proprio$nom))
##
## FALSE
## 20333
# tous les proprio ont un nom.
head(proprio$nom [is.na(proprio$categorie)])
## [1] "LEBERVET/ "
## [2] "DOUARIN/MARIE JEANNE "
## [3] "VILLALBA/DAVID "
## [4] "CHAVE/PASCAL GILLES PAUL "
## [5] "MANSOURI/NADIA "
## [6] "MARZOUKI/MOUNIR "
proprio <- unique(proprio)
proprio$nom <- gsub("^\\s+|\\s+$", "", proprio$nom)
# expression régulière tous les débuts et tous les fin
# + une ou pl répétitions (quantificateur)
# \ échappement
# \s espace
table(proprio$categorie, useNA = "always")
##
## 0 1 2 3 4 5 6 7 9 <NA>
## 855 8 1 2 5 17 3 582 10 18099
# 19307 / 19468 proprios répertoriés
jointure <- merge(agg, proprio, by = "nom", all.x = T)
st_write(jointure, "../data/cadastre.gpkg", "pmorale", delete_layer = T)
## Deleting layer `pmorale' using driver `GPKG'
## Writing layer `pmorale' to data source `../data/cadastre.gpkg' using driver `GPKG'
## Writing 5582 features with 4 fields and geometry type Unknown (any).
1008 en jointure seulement, on force all.x pour avoir toutes les parcelles du cadastre.
TODO pourquoi seulement 1008 ? Il y avait 20 M propriétaries…
data <- st_read("../data/cadastre.gpkg", "pmorale", quiet = T)
# on force en polygone (cela éclate les parcelles non adjacentes)
data <- st_cast(data, "POLYGON")
table(data$categorie)
##
## 0 1 2 3 4 5 6 7 9
## 460 5 1 23 86 75 4 10902 57
# la categ 8 n'existe pas.
i <- 0
mf_export(data, filename = "../img/pmorale.png", theme = "brutal")
par (mfrow = c(3,3))
for (i in 0:9){
if (i!=8){
j <- i+1
mf_map(data [data$categorie == i,])
mf_layout(paste0(i," : ",cat[j]), credits = "")
}
}
dev.off()
## png
## 2
On repart de la couche comprenant les personnes morales.
Pour mémoire, le fichier est une agrégation de parcelles par nom de propriétaires (cas des biens sans maitre).
On s’inspire du code DGFiP et de la catégorisation de Bobigny
La méthode pour catégoriser est selon le cas :
recherche d’un motif dans la chaîne de caractère (cas des SCI par exemple)
Utilisation de table d’équivalence exportée, puis modifiée sous tableur et enfin ré-intégrée. (cas des bailleurs sociaux)
En recherchant un motif, on peu identifier : copro, individus, et absence de données.
Mais on peut également isoler les SCI (au sein des personnes morales non remarquables).
Du coup, il y aura beaucoup de modalités dans la variable categ2.
Pour agréger, de façon intuitive on distinguera public / privé et autres (variable categ1).
# on reprend le fichier p. morale
data <- st_read("../data/cadastre.gpkg", "pmorale")
## Reading layer `pmorale' from data source
## `C:\Users\tachasa\02_cartos\data\cadastre.gpkg' using driver `GPKG'
## Simple feature collection with 5582 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 661077.2 ymin: 6865338 xmax: 663343.6 ymax: 6869045
## Projected CRS: RGF93 / Lambert-93
#initialisation nécessaire pour effectuer les remplacements
data$categ1 <- NA
data$categ2 <- NA
# M MME
ind1 <- grep("M |MME ", data$nom)
data$categ2 [ind1] <- "Personne physique (M / MME)"
ind2 <- grep("COPRO|PROPRI", data$nom)
data$categ2 [ind2] <- "Copropriété"
# Il semble intéressant d'éclater la catégorie *personne morale non remarquable* en retirant les SCI
ind3 <- grep("SCI|SOCIETE CIVILE IMMOBILIERE|SOCIETE CIVILE IMMOBILIERE|STE CIVILE IMMOBILIERE|S C I ", data$nom)
data$categ2 [ind3] <- "SCI"
data$categ2 [data$nom == "inconnu"] <- "Absence de données ou mutation en cours"
data$categ1 [data$nom == "inconnu"] <- "AUTRES"
data$categ1 [c(ind1,ind2, ind3)] <- "PRIVES"
st_write(data,"../data/cadastre.gpkg","pmorale", delete_layer=T)
## Deleting layer `pmorale' using driver `GPKG'
## Writing layer `pmorale' to data source `../data/cadastre.gpkg' using driver `GPKG'
## Writing 5582 features with 6 fields and geometry type Multi Polygon.
data <- st_read("../data/cadastre.gpkg", "pmorale", quiet = T)
EPI <- c("SNCF", "RATP", "EAUX")
chercher <- function(str) {grep(str, data$nom)}
ind <- unlist(sapply(EPI, chercher))
data$categ2 [ind] <- "Etablissements publics et institutionnels"
data$categ1 [ind] <- "Public"
png("../img/motif.png", width = 1000, height = 1000, res = 120)
mf_map(data, type = "typo", var = "categ2", border = NA)
mf_layout(title = "Recherche motif dans nom propriétaire cadastre", credits = "Bondy / DGST\nsources : cadastre 2022")
dev.off()
## png
## 2
Le nom des bailleurs n’est pas orthographié à l’identique entre l’inventaire et le cadastre.
bailleurs <- read.csv("../data/bailleurs.csv")
# liste issue de l'inventaire social, on cherche une correspondance à 5 caractères
indBailleurs <- function(bailleur){grep(substr(bailleur,1,5), data$nom)}
ind <- unlist(sapply(bailleurs, indBailleurs))
write.csv(data$nom [ind], "../data/tableCorrespondance.csv", fileEncoding = "UTF-8")
On extrait les noms et on leur attribue un type.
Utilisation de la table de correspondance établie
listeBailleurs <- read.csv("../data/tableCorrespondanceRep.csv", fileEncoding = "UTF-8")
listeBailleurs$nom <- gsub("^\\s+|\\s+$", "", listeBailleurs$nom)
listeBailleurs$motif
## [1] "ADEF"
## [2] "ADOMA"
## [3] "BATIGERE"
## [4] ""
## [5] ""
## [6] ""
## [7] ""
## [8] ""
## [9] ""
## [10] "BONDY HABITAT"
## [11] ""
## [12] ""
## [13] ""
## [14] ""
## [15] ""
## [16] ""
## [17] ""
## [18] ""
## [19] ""
## [20] ""
## [21] "CDC"
## [22] "CDC"
## [23] ""
## [24] ""
## [25] "3F"
## [26] ""
## [27] ""
## [28] ""
## [29] ""
## [30] ""
## [31] ""
## [32] ""
## [33] ""
## [34] ""
## [35] "SOFILOGIS"
## [36] ""
## [37] ""
## [38] "OFFICE PUBLIC HABITAT SEINE SAINT DENIS"
## [39] ""
## [40] "SEQENS"
listeMotif <- listeBailleurs [(listeBailleurs$motif)!="",]
listeMotif
## nom proposition
## 1 ADEF RESIDENCES bailleur
## 2 ADOMA bailleur
## 3 BATIGERE EN ILE DE FRANCE bailleur
## 10 BONDY HABITAT OFFICE PUBLIC DE L'HABITAT D'EST ENSEMBLE bailleur
## 21 CDC HABITAT SOCIAL SOCIETE ANONYME D'HABITATIONS A LOYER MOD bailleur
## 22 CDC HABITAT SOCIAL SOCIETE ANONYME D'HABITATIONS A LOYER MOD bailleur
## 25 IMMOBILIERE 3F bailleur
## 35 SOFILOGIS bailleur
## 38 OFFICE PUBLIC HABITAT SEINE SAINT DENIS bailleur
## 40 SEQENS SOCIETE ANONYME D'HABITATIONS A LOYER MODERE bailleur
## motif
## 1 ADEF
## 2 ADOMA
## 3 BATIGERE
## 10 BONDY HABITAT
## 21 CDC
## 22 CDC
## 25 3F
## 35 SOFILOGIS
## 38 OFFICE PUBLIC HABITAT SEINE SAINT DENIS
## 40 SEQENS
listeMotif <- listeMotif [-5,]
# Exemple avec ADEF
grep('ADEF', data$nom)
## [1] 17
data$nom [17]
## [1] "ADEF RESIDENCES"
grep('ADOMA', data$nom)
## [1] 19
data$nom [grep('ADOMA', data$nom)]
## [1] "ADOMA"
data <- st_read("../data/cadastre.gpkg","pmorale", quiet = T)
# boucle sur le motif pour recoder le cadastre
i <- 1
for (i in (1:8)) {
print(listeMotif$motif [i] )
ind <- grep(listeMotif$motif [i], data$nom)
print(data$nom [ind])
data$nom [ind] <- listeMotif$nom [i]
}
## [1] "ADEF"
## [1] "ADEF RESIDENCES"
## [1] "ADOMA"
## [1] "ADOMA"
## [1] "BATIGERE"
## [1] "BATIGERE EN ILE DE FRANCE"
## [1] "BONDY HABITAT"
## [1] "BONDY HABITAT OFFICE PUBLIC DE L'HABITAT D'EST ENSEMBLE"
## [2] "BONDY HABITAT OFFICE PUBLIC DE L'HABITAT D'EST ENSEMBLE"
## [1] "CDC"
## [1] "CDC HABITAT SOCIAL SOCIETE ANONYME D'HABITATIONS A LOYER MOD"
## [1] "3F"
## [1] "IMMOBILIERE 3F"
## [1] "SOFILOGIS"
## character(0)
## [1] "OFFICE PUBLIC HABITAT SEINE SAINT DENIS"
## character(0)
Problème sur l’OPH départemental, il existe mais on arrive pas à le trouver…
jointure <- merge (data, listeBailleurs, by = "nom", all.x = T)
Il faudrait exploiter plusieurs sources pour établir une liste des commerces :
fichier des enseignes
liste des ERP
liste du service commerce
Recoupage des informations avec la donnée cadastrale
knitr::kable(table(data$categorie, data$categ1, useNA = "always"))
| AUTRES | PRIVES | NA | |
|---|---|---|---|
| 0 | 0 | 129 | 264 |
| 1 | 0 | 0 | 2 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 0 | 2 |
| 4 | 0 | 0 | 4 |
| 5 | 0 | 1 | 11 |
| 6 | 0 | 0 | 3 |
| 7 | 0 | 578 | 3 |
| 9 | 0 | 0 | 9 |
| NA | 1 | 4570 | 4 |
2 bailleurs hors catégorie 5
On a récupéré tous les propriétaires particuliers qui n’étaient pas des personnes morales.
Il y seulement 4 propriétaires inclassables…
data [is.na(data$categ1)&is.na(data$categorie),]
## Simple feature collection with 4 features and 6 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 661598.9 ymin: 6866039 xmax: 662867.5 ymax: 6868597
## Projected CRS: RGF93 / Lambert-93
## nom nb_parcelles categorie dsiren categ1 categ2
## 354 L 1 <NA> <NA> <NA> <NA>
## 358 LA MAISON DE SOS FEMMES 93 1 <NA> <NA> <NA> <NA>
## 5512 SDC LES PEUPLIERS 210 1 <NA> <NA> <NA> <NA>
## 5567 VEES/GLORIA 1 <NA> <NA> <NA>
## geom
## 354 MULTIPOLYGON (((662867.5 68...
## 358 MULTIPOLYGON (((661625.6 68...
## 5512 MULTIPOLYGON (((662274.7 68...
## 5567 MULTIPOLYGON (((661679.9 68...